﻿// LineDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "VideoPlayer.h"
#include "LineDlg.h"
#include "afxdialogex.h"

UINT LineThreadShowPic(PVOID pParam);
// CLineDlg 对话框

IMPLEMENT_DYNAMIC(CLineDlg, CDialogEx)

CLineDlg::CLineDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(IDD_DLG_LINE, pParent)
{

}

CLineDlg::~CLineDlg()
{
}

void CLineDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(CLineDlg, CDialogEx)
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_BN_CLICKED(IDOK, &CLineDlg::OnBnClickedOk)
	ON_WM_RBUTTONDOWN()
	ON_COMMAND(ID_32773, &CLineDlg::On32773)
END_MESSAGE_MAP()


// CLineDlg 消息处理程序
// CAreaDlg 消息处理程序
BOOL CLineDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时，框架将自动
	//  执行此操作
	if (GetDlgItem(IDC_LINE_PIC) != NULL)
		GetDlgItem(IDC_LINE_PIC)->GetClientRect(&m_rect);
	int no = g_pLightQueue->getLastFrameNo();
	//队列为空（尚未开机）
	if (no == 0) {
		MessageBox(_T("请打开相机"));
		return TRUE;
	}
	g_pLightQueue->getLast(m_Frame);
	//此处一定要clone，否则在onDisplay中进行的绘制操作，都会被其他模块中getLast时带入
	m_Frame.frame = m_Frame.frame.clone();
	CWinThread* pShowThread = AfxBeginThread(LineThreadShowPic, this, THREAD_PRIORITY_ABOVE_NORMAL, 0, CREATE_SUSPENDED);
	pShowThread->m_bAutoDelete = FALSE;
	pShowThread->ResumeThread();
	for (int i = 0; i < g_pMainDlg->m_lineV.size(); i++) {
		m_points_relative.push_back(g_pMainDlg->m_lineV[i]);
	}
	return TRUE;  // 除非将焦点设置到控件，否则返回 TRUE
}
/*******************************************************************************
* 可见光显示线程
* @yuv      待显示帧
* @frameNo  待显示帧帧号
******************************************************************************/
UINT LineThreadShowPic(PVOID pParam) {
	Sleep(500);
	CLineDlg* pThis = (CLineDlg*)pParam;
	pThis->OnDisplay();
	return 0;
}
void CLineDlg::getRelativePos(CPoint& p) {
	CRect rect;
	GetDlgItem(IDC_LINE_PIC)->GetWindowRect(&rect);
	this->ClientToScreen(&p);
	CPoint rectTL = rect.TopLeft();
	LONG rx_1 = p.x - rectTL.x;
	LONG ry_1 = p.y - rectTL.y;
	float wRatio = (float)m_Frame.frame.cols / m_rect.Width();
	float hRatio = (float)m_Frame.frame.rows / m_rect.Height();
	CvPoint tlPoint = cvPoint((int)rx_1*wRatio, (int)ry_1*hRatio);
	p.x = tlPoint.x;
	p.y = tlPoint.y;
}

void CLineDlg::OnDisplay()  //负责调整大小后调用display显示到picture控件
{
	Mat tempFrame = m_Frame.frame.clone();
	if (m_Drawing) {
		CRect rect;
		GetDlgItem(IDC_LINE_PIC)->GetWindowRect(&rect);
		CPoint rectTL = rect.TopLeft();
		m_points_relative[m_points_relative.size() - 1].clear();
		float wRatio = (float)m_Frame.frame.cols / m_rect.Width();
		float hRatio = (float)m_Frame.frame.rows / m_rect.Height();
		for (int i = 0; i < m_points.size(); i++)
		{
			CPoint p(m_points[i].x, m_points[i].y);
			this->ClientToScreen(&p);
			m_points_relative[m_points_relative.size()-1].push_back(cvPoint((int)((p.x - rectTL.x)*wRatio), (int)((p.y - rectTL.y)*hRatio)));
		}
	}
	for (int i = 0; i < m_points_relative.size(); i++)
	{
		vector<CvPoint> line = m_points_relative[i];
		for (int j = 0; j < (line.size()-1); j++) {
			CvPoint p1 = cvPoint(line[j].x, line[j].y);
			CvPoint p2 = cvPoint(line[j + 1].x, line[j + 1].y);
			cv::line(tempFrame, p1, p2, Scalar(0, 0, 255), 2, 1, 0);
		}
		
	}
	IplImage iplImage(tempFrame); //转换成IplImage类型
	CDC* pDC = GetDlgItem(IDC_LINE_PIC)->GetDC();
	CvvImage cvImg;
	cvImg.CopyOf(&iplImage);
	cvImg.DrawToHDC(pDC->m_hDC, &m_rect);
	ReleaseDC(pDC);

}

void CLineDlg::OnLButtonDown(UINT nFlags, CPoint point) {
	m_points.clear();
	m_Drawing = true;
	m_points.push_back(cvPoint(point.x, point.y));
	vector<CvPoint> v;
	v.push_back(cvPoint(point.x, point.y));
	m_points_relative.push_back(v);
}

void CLineDlg::OnMouseMove(UINT nFlags, CPoint point)

{
	if (m_Drawing) {
		m_points.push_back(cvPoint(point.x, point.y));
		OnDisplay();
	}
}

void CLineDlg::OnLButtonUp(UINT nFlags, CPoint point) {

	if (m_Drawing) {
		m_Drawing = false;
	}
}

void CLineDlg::OnBnClickedOk()
{
	// TODO: 在此添加控件通知处理程序代码
	g_pMainDlg->m_lineV.clear();
	for (int i = 0; i < m_points_relative.size(); i++) {
		g_pMainDlg->m_lineV.push_back(m_points_relative[i]);
	}
	CDialogEx::OnOK();
}

static CPoint rcPoint; //右点击点的坐标
void CLineDlg::OnRButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	int index = -1;
	rcPoint = point;
	getRelativePos(rcPoint);
	for (int i = 0; i < m_points_relative.size(); i++) {
		if (CUtils::inLine(rcPoint, m_points_relative[i])) {
			index = i;
			break;
		}
	}
	if (index == -1) {
		return;
	}

	CMenu menu;
	menu.LoadMenu(IDR_MENU1); //装载自定义的右键菜单 
	CMenu *pContextMenu = menu.GetSubMenu(0); //获取第一个弹出菜单，所以第一个菜单必须有子菜单 
	CPoint point1;//定义一个用于确定光标位置的位置  
	GetCursorPos(&point1);//获取当前光标的位置，以便使得菜单可以跟随光标  
	pContextMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point1.x, point1.y, this); //在指定位置显示弹出菜单
	CDialogEx::OnRButtonDown(nFlags, point);
}




void CLineDlg::On32773()
{
	// TODO: 在此添加命令处理程序代码
	cout << rcPoint.x << rcPoint.y << endl;
	
	int index = -1;
	for (int i = 0; i < m_points_relative.size(); i++) {
		if (CUtils::inLine(rcPoint, m_points_relative[i])) {
			index = i;
			break;
		}
	}
	if (index != -1) {
		std::vector<vector<CvPoint>>::iterator it = m_points_relative.begin() + index;
		m_points_relative.erase(it);
		OnDisplay();
	}
}
